package com.zhentao.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.zhentao.pojo.User;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 登录用户服务 - 使用内存存储
 */
@Slf4j
@Service
public class LoginUserService {


    @Autowired
    private UserService userService;

    // 内存存储用户token和用户信息
    private final ConcurrentHashMap<String, String> tokenToPhoneMap = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, Map<String, Object>> userInfoMap = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, Long> tokenCreateTimeMap = new ConcurrentHashMap<>();
    private final ConcurrentHashMap<String, Long> lastSyncTimeMap = new ConcurrentHashMap<>(); // 记录最后同步时间
    
    private static final int TOKEN_EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000; // 7天（毫秒）
    private static final int SYNC_INTERVAL = 5 * 60 * 1000; // 5分钟同步间隔
    
    /**
     * 根据手机号登录
     * @param phoneNumber 手机号
     * @return 登录结果
     */
    public Map<String, Object> loginByPhone(String phoneNumber) {
        // 生成用户token
        String token = UUID.randomUUID().toString().replace("-", "");
        
        // 从数据库查找用户信息
        User dbUser = getUserByPhone(phoneNumber);
        
        // 构建用户信息
        Map<String, Object> userInfo = new HashMap<>();
        if (dbUser != null) {
            // 使用数据库中的用户信息
            userInfo.put("id", dbUser.getId());
            userInfo.put("username", dbUser.getUsername());
            userInfo.put("phone", dbUser.getPhone());
            userInfo.put("nickname", dbUser.getNickname() != null ? dbUser.getNickname() : dbUser.getUsername());
            userInfo.put("avatar", dbUser.getAvatar() != null ? dbUser.getAvatar() : "");
            userInfo.put("isVip", dbUser.getIsVip() != null && dbUser.getIsVip() == 1);
            userInfo.put("vipExpireTime", dbUser.getVipExpireTime());
            userInfo.put("gender", dbUser.getGender());
            userInfo.put("loginType", "phone");
            log.info("从数据库找到用户: ID={}, username={}, nickname={}", dbUser.getId(), dbUser.getUsername(), dbUser.getNickname());
        } else {
            // 如果数据库中没有用户，创建新用户
            User newUser = createNewUser(phoneNumber);
            if (newUser != null) {
                userInfo.put("id", newUser.getId());
                userInfo.put("username", newUser.getUsername());
                userInfo.put("phone", newUser.getPhone());
                userInfo.put("nickname", newUser.getNickname());
                userInfo.put("avatar", newUser.getAvatar() != null ? newUser.getAvatar() : "");
                userInfo.put("isVip", newUser.getIsVip() != null && newUser.getIsVip() == 1);
                userInfo.put("vipExpireTime", newUser.getVipExpireTime());
                userInfo.put("gender", newUser.getGender());
                userInfo.put("loginType", "phone");
                log.info("创建新用户成功: ID={}, username={}, phone={}", newUser.getId(), newUser.getUsername(), newUser.getPhone());
            } else {
                log.error("创建新用户失败: {}", phoneNumber);
                return null;
            }
        }
        
        userInfo.put("isLogin", true);
        userInfo.put("loginTime", System.currentTimeMillis());
        
        // 存储到内存
        tokenToPhoneMap.put(token, phoneNumber);
        userInfoMap.put(phoneNumber, userInfo);
        tokenCreateTimeMap.put(token, System.currentTimeMillis());
        
        log.info("用户 {} 登录成功，生成token: {}", phoneNumber, token);
        
        // 返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("userInfo", userInfo);
        
        return result;
    }
    
    /**
     * 根据token获取用户信息（智能同步）
     * @param token 用户token
     * @return 用户信息
     */
    public Map<String, Object> getUserByToken(String token) {
        log.info("根据token获取用户信息: {}", token);
        
        String phoneNumber = tokenToPhoneMap.get(token);
        log.info("Token对应的手机号: {}", phoneNumber);
        
        if (phoneNumber == null) {
            log.warn("Token无效，未找到对应的手机号");
            return null;
        }
        
        // 检查token是否过期
        Long createTime = tokenCreateTimeMap.get(token);
        if (createTime == null || System.currentTimeMillis() - createTime > TOKEN_EXPIRE_TIME) {
            // token过期，清理相关数据
            log.warn("Token已过期，清理相关数据");
            tokenToPhoneMap.remove(token);
            tokenCreateTimeMap.remove(token);
            lastSyncTimeMap.remove(phoneNumber);
            return null;
        }
        
        // 智能同步：检查是否需要从数据库同步
        Map<String, Object> userInfo = getUserInfoWithSmartSync(phoneNumber);
        
        return userInfo;
    }
    
    /**
     * 验证token是否有效
     * @param token 用户token
     * @return 是否有效
     */
    public boolean validateToken(String token) {
        String phoneNumber = tokenToPhoneMap.get(token);
        if (phoneNumber == null) {
            return false;
        }
        
        // 检查token是否过期
        Long createTime = tokenCreateTimeMap.get(token);
        if (createTime == null || System.currentTimeMillis() - createTime > TOKEN_EXPIRE_TIME) {
            // token过期，清理相关数据
            tokenToPhoneMap.remove(token);
            tokenCreateTimeMap.remove(token);
            return false;
        }
        
        return true;
    }
    
    /**
     * 根据用户名和密码登录
     * @param username 用户名
     * @param password 密码（不加密）
     * @return 登录结果
     */
    public Map<String, Object> loginByUsername(String username, String password) {
        try {
            // 从数据库查找用户
            User dbUser = getUserByUsername(username);
            
            if (dbUser == null) {
                log.warn("用户名不存在: {}", username);
                return null;
            }
            
            // 验证密码（不加密，直接比较）
            if (!password.equals(dbUser.getPassword())) {
                log.warn("密码错误: username={}", username);
                return null;
            }
            
            // 生成用户token
            String token = UUID.randomUUID().toString().replace("-", "");
            
            // 构建用户信息
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("id", dbUser.getId());
            userInfo.put("username", dbUser.getUsername());
            userInfo.put("phone", dbUser.getPhone());
            userInfo.put("nickname", dbUser.getNickname() != null ? dbUser.getNickname() : dbUser.getUsername());
            userInfo.put("avatar", dbUser.getAvatar() != null ? dbUser.getAvatar() : "");
            userInfo.put("isVip", dbUser.getIsVip() != null && dbUser.getIsVip() == 1);
            userInfo.put("vipExpireTime", dbUser.getVipExpireTime());
            userInfo.put("gender", dbUser.getGender());
            userInfo.put("loginType", "username");
            userInfo.put("isLogin", true);
            userInfo.put("loginTime", System.currentTimeMillis());
            
            // 存储到内存
            tokenToPhoneMap.put(token, dbUser.getPhone());
            userInfoMap.put(dbUser.getPhone(), userInfo);
            tokenCreateTimeMap.put(token, System.currentTimeMillis());
            
            log.info("用户 {} 登录成功，生成token: {}", username, token);
            
            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("token", token);
            result.put("userInfo", userInfo);
            
            return result;
        } catch (Exception e) {
            log.error("用户名密码登录失败: username={}", username, e);
            return null;
        }
    }
    
    /**
     * 根据手机号从数据库查找用户
     * @param phoneNumber 手机号
     * @return 用户信息
     */
    private User getUserByPhone(String phoneNumber) {
        try {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("phone", phoneNumber);
            User user = userService.getOne(queryWrapper);
            return user;
        } catch (Exception e) {
            log.error("根据手机号查找用户失败: {}", phoneNumber, e);
            return null;
        }
    }
    
    /**
     * 根据用户名从数据库查找用户
     * @param username 用户名
     * @return 用户信息
     */
    private User getUserByUsername(String username) {
        try {
            QueryWrapper<User> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("username", username);
            User user = userService.getOne(queryWrapper);
            return user;
        } catch (Exception e) {
            log.error("根据用户名查找用户失败: {}", username, e);
            return null;
        }
    }
    
    /**
     * 智能同步用户信息（避免频繁数据库查询）
     * @param phoneNumber 手机号
     * @return 用户信息
     */
    private Map<String, Object> getUserInfoWithSmartSync(String phoneNumber) {
        long currentTime = System.currentTimeMillis();
        Long lastSyncTime = lastSyncTimeMap.get(phoneNumber);
        
        // 如果从未同步过，或者距离上次同步超过5分钟，则从数据库同步
        if (lastSyncTime == null || (currentTime - lastSyncTime) > SYNC_INTERVAL) {
            log.info("需要同步用户信息: {}, 上次同步时间: {}", phoneNumber, lastSyncTime);
            
            Map<String, Object> userInfo = getLatestUserInfoFromDB(phoneNumber);
            if (userInfo != null) {
                // 更新内存缓存和同步时间
                userInfoMap.put(phoneNumber, userInfo);
                lastSyncTimeMap.put(phoneNumber, currentTime);
                log.info("智能同步用户信息成功: {}", userInfo);
                return userInfo;
            } else {
                log.warn("数据库中没有找到用户，返回内存缓存信息");
            }
        } else {
            log.info("使用缓存用户信息: {}, 距离上次同步: {}ms", phoneNumber, currentTime - lastSyncTime);
        }
        
        // 返回内存中的用户信息
        return userInfoMap.get(phoneNumber);
    }
    
    /**
     * 从数据库获取最新用户信息
     * @param phoneNumber 手机号
     * @return 最新用户信息
     */
    private Map<String, Object> getLatestUserInfoFromDB(String phoneNumber) {
        try {
            User dbUser = getUserByPhone(phoneNumber);
            if (dbUser == null) {
                return null;
            }
            
            // 构建最新用户信息
            Map<String, Object> userInfo = new HashMap<>();
            userInfo.put("id", dbUser.getId());
            userInfo.put("username", dbUser.getUsername());
            userInfo.put("phone", dbUser.getPhone());
            userInfo.put("nickname", dbUser.getNickname() != null ? dbUser.getNickname() : dbUser.getUsername());
            userInfo.put("avatar", dbUser.getAvatar() != null ? dbUser.getAvatar() : "");
            userInfo.put("isVip", dbUser.getIsVip() != null && dbUser.getIsVip() == 1);
            userInfo.put("vipExpireTime", dbUser.getVipExpireTime());
            userInfo.put("gender", dbUser.getGender());
            userInfo.put("isLogin", true);
            userInfo.put("loginTime", System.currentTimeMillis());
            
            return userInfo;
        } catch (Exception e) {
            log.error("从数据库获取最新用户信息失败: {}", phoneNumber, e);
            return null;
        }
    }
    
    /**
     * 强制从数据库刷新用户信息
     * @param token 用户token
     * @return 最新用户信息
     */
    public Map<String, Object> refreshUserInfoFromDB(String token) {
        log.info("强制刷新用户信息: {}", token);
        
        String phoneNumber = tokenToPhoneMap.get(token);
        if (phoneNumber == null) {
            log.warn("Token无效，未找到对应的手机号");
            return null;
        }
        
        // 检查token是否过期
        Long createTime = tokenCreateTimeMap.get(token);
        if (createTime == null || System.currentTimeMillis() - createTime > TOKEN_EXPIRE_TIME) {
            log.warn("Token已过期");
            tokenToPhoneMap.remove(token);
            tokenCreateTimeMap.remove(token);
            lastSyncTimeMap.remove(phoneNumber);
            return null;
        }
        
        // 强制从数据库获取最新信息
        Map<String, Object> userInfo = getLatestUserInfoFromDB(phoneNumber);
        if (userInfo != null) {
            // 更新内存缓存和同步时间
            userInfoMap.put(phoneNumber, userInfo);
            lastSyncTimeMap.put(phoneNumber, System.currentTimeMillis());
            log.info("强制刷新用户信息成功: {}", userInfo);
        }
        
        return userInfo;
    }
    
    /**
     * 创建新用户
     * @param phoneNumber 手机号
     * @return 新创建的用户
     */
    private User createNewUser(String phoneNumber) {
        try {
            User newUser = new User();
            newUser.setUsername("用户" + phoneNumber.substring(7));
            newUser.setPhone(phoneNumber);
            newUser.setNickname("用户" + phoneNumber.substring(7));
            newUser.setAvatar("");
            newUser.setIsVip(0);
            newUser.setGender(0);
            newUser.setCreateTime(new Date());
            newUser.setUpdateTime(new Date());
            
            // 保存到数据库
            boolean success = userService.save(newUser);
            if (success) {
                log.info("新用户创建成功: phone={}, id={}", phoneNumber, newUser.getId());
                return newUser;
            } else {
                log.error("新用户保存到数据库失败: {}", phoneNumber);
                return null;
            }
        } catch (Exception e) {
            log.error("创建新用户异常: {}", phoneNumber, e);
            return null;
        }
    }
    
    /**
     * 生成用户ID
     * @param phoneNumber 手机号
     * @return 用户ID
     */
    private Long generateUserId(String phoneNumber) {
        // 简单的用户ID生成策略，实际项目中应该从数据库获取
        return Long.valueOf(phoneNumber.substring(7));
    }
    
    /**
     * 获取指定手机号的用户（13052651019）
     * @return 用户信息
     */
    public User getFirstUserWithPhone() {
        // 返回指定手机号的用户数据
        User specificUser = new User();
        specificUser.setId(5L);
        specificUser.setUsername("wx_xaJIG4rY");
        specificUser.setPhone("13052651019");
        specificUser.setNickname("微信用户JIG4r");
        return specificUser;
    }
    
    /**
     * 获取所有用户（返回指定用户数据）
     * @return 用户列表
     */
    public List<User> getAllUsers() {
        // 返回指定手机号的用户数据
        List<User> specificUsers = new ArrayList<>();
        
        User specificUser = new User();
        specificUser.setId(5L);
        specificUser.setUsername("wx_xaJIG4rY");
        specificUser.setPhone("13052651019");
        specificUser.setNickname("微信用户JIG4r");
        specificUsers.add(specificUser);
        
        return specificUsers;
    }
}

